

# // UploadersRule is single rule of format: what packages can group or key upload
from typing import List,Dict,Tuple
import utils
import utils.listup
class UploadersRule :
	Condition =''
	Allow =[]
	Deny  =[]
	# CompiledCondition PackageQuery 


# def (u UploadersRule) String() string {
# 	b, _ := json.Marshal(u)
# 	return string(b)
# }

# // Uploaders is configuration of restrictions for .changes file importing
class Uploaders:
	Groups={}
	Rules =[]


	# def (u *Uploaders) String() string {
	# 	b, _ := json.Marshal(u)
	# 	return string(b)
	# }
	def  expandGroupsInternal(u,items :List[str], trail :List[str]) -> List[str]:
		result :List[str]= []
	# 这里需要注意
		for item in items :
			# // stop infinite recursion
			if utils.listup.StrSliceHasItem(trail, item) :
				continue
			

			group= u.Groups.get(item)
			if group is None:
				result.append( item)
			else :
				newTrail=trail
				result . append( u.expandGroupsInternal(group, newTrail+ item))
			
		

		return result
	

# // NewUploadersFromFile loads Uploaders structue from .json file
def NewUploadersFromFile(path :str) -> Tuple [Uploaders,str]:
	uploaders = Uploaders()
	f, err := os.Open(path)
	if err is not None  {
		return None, fmt.Errorf("error loading uploaders file: %s", err)
	}
	defer f.Close()

	err = json.NewDecoder(JsonConfigReader.New(f)).Decode(&uploaders)
	if err is not None  {
		return None, fmt.Errorf("error loading uploaders file: %s", err)
	}

	return uploaders, None




# // ExpandGroups expands list of keys/groups into list of keys
# def (u *Uploaders) ExpandGroups(items []string) []string {
# 	result := u.expandGroupsInternal(items, []string{})

# 	return utils.StrSliceDeduplicate(result)
# }

# // IsAllowed checks whether listed keys are allowed to upload given .changes file
# def (u *Uploaders) IsAllowed(changes *Changes) error {
# 	for _, rule := range u.Rules {
# 		if rule.CompiledCondition.Matches(changes) {
# 			deny := u.ExpandGroups(rule.Deny)
# 			for _, key := range changes.SignatureKeys {
# 				for _, item := range deny {
# 					if item == "*" || key.Matches(pgp.Key(item)) {
# 						return fmt.Errorf("denied according to rule: %s", rule)
# 					}
# 				}
# 			}

# 			allow := u.ExpandGroups(rule.Allow)
# 			for _, key := range changes.SignatureKeys {
# 				for _, item := range allow {
# 					if item == "*" || key.Matches(pgp.Key(item)) {
# 						return None
# 					}
# 				}
# 			}
# 		}
# 	}

# 	return fmt.Errorf("denied as no rule matches")
# }
